import datetime
from config import BUCKETNAME, duckdb
from scraper import scrapePages

today = datetime.datetime.now().strftime('%Y-%m-%d')


def save_to_s3(dfname, filename):
    """
    This function takes a pandas dataframe
    and saves it to an S3 bucket as a parquet file.

    Parameters:
        dfname (str): The pandas DataFrame name to be saved.
        filename (str): The name of the S3 file where the data will be stored.
    Returns:
        str: A string representing the URL of the saved file in the S3 bucket.
    """
    if not filename:
        raise Exception("You need provide a filename for dataframe")
    s3_url = f's3://{BUCKETNAME}/{filename}'
    duckdb.sql(f"COPY {dfname} TO '{s3_url}';")


def load_save_today_repos():
    # Скрапим все страницы с gitverse за сегодня
    df = scrapePages()
    print(df.shape)
    today_dataset = f"repos_gitverse_{today}.parquet"
    # Сохраняем dataset на s3
    save_to_s3("df", today_dataset)
    # Сохраняем dataset локально
    duckdb.execute(f"""
        COPY (SELECT * FROM df)
        TO './datasets/repos_gitverse_{today}.parquet' (FORMAT PARQUET);
    """)

    # Проверяем датасет с s3 хранилища
    s3_url = f's3://{BUCKETNAME}/{today_dataset}'
    duckdb.execute(f"""
        CREATE VIEW gitverse AS SELECT * FROM parquet_scan('{s3_url}');
    """)
    new_rows_today = duckdb.sql("SELECT COUNT(*) FROM gitverse;").fetchone()[0]
    print(f"Сегодня на Gitverse всего репозиториев: {new_rows_today}")


def mix_today_data_with_full_archive():
    filename = f"repos_gitverse_{today}.parquet"
    s3_url = f"s3://{BUCKETNAME}/{filename}"

    duckdb.execute(f"""
        CREATE VIEW gitverse_today
        AS SELECT * FROM parquet_scan('{s3_url}');""")

    new_rows_today = duckdb.sql("""
        SELECT COUNT(*) FROM gitverse_today;
        """).fetchone()[0]

    if new_rows_today < 10:
        raise Exception("Today's dataset is too small!")

    # Импорт текущего датасета за весь период времени
    duckdb.execute(
        f"""
        CREATE TABLE gitverse_alltime
        AS SELECT *
        FROM parquet_scan('s3://{BUCKETNAME}/repos_gitverse.parquet');"""
    )

    last_day_in_dataset = duckdb.sql("""
        SELECT created_at
        FROM gitverse_alltime
        ORDER BY created_at DESC
        LIMIT 1;""").fetchone()[0]

    # Сохраняем dataset локально
    duckdb.execute("""
        COPY (SELECT * FROM gitverse_alltime)
        TO './datasets/repos_gitverse.parquet' (FORMAT PARQUET);
    """)
    if last_day_in_dataset.date() == datetime.datetime.now().date():
        print("Alltime dataset уже был обновлен сегодня")
        return

    print("Обновляем большой датасет")
    # Создания копии датасета
    duckdb.sql(
        f"""
        COPY gitverse_alltime
        TO 's3://{BUCKETNAME}/repos_gitverse_archive.parquet';"""
    )
    # Смешиваем старые данные с новым днем
    duckdb.sql("INSERT INTO gitverse_alltime SELECT * FROM gitverse_today;")
    # Сохраняем dataset на s3
    duckdb.sql(f"""
        COPY gitverse_alltime
        TO 's3://{BUCKETNAME}/repos_gitverse.parquet';""")
    # Сохраняем dataset локально
    duckdb.execute("""
        COPY (SELECT * FROM gitverse_alltime)
        TO './datasets/repos_gitverse.parquet' (FORMAT PARQUET);
    """)
    print("👊Датасет обновлен! ")


def update_readme():
    duckdb.execute(f"""
        CREATE VIEW IF NOT EXISTS gitverse_today
        AS SELECT *
        FROM parquet_scan('./datasets/repos_gitverse_{today}.parquet');""")
    repos_today_cnt = duckdb.execute("""
        SELECT COUNT(*)
        FROM gitverse_today
    """).fetchall()[0][0]
    lang_df = duckdb.sql("""
        SELECT lang, COUNT(*) as count
        FROM gitverse_today GROUP BY lang;
    """).df()
    lang_df = lang_df.sort_values(by='count', ascending=False).dropna()
    top_10_languages = lang_df[:10]

    print(f"Сегодня репозиториев на Gitverse {repos_today_cnt} шт.")
    print(f"На сегодня Gitverse топ 10 ЯП {top_10_languages}")

    with open('./README.md', 'w') as f:
        f.write(f"""
# Gitverse dataset\n

Тут мы скрапим публичные репозитории с Gitverse и
анализируем их.

Цель - определить состояние платформы
её востребованность и уровень жизни.

С помощью этих данных можно проследить жизненный цикл
не только Gitverse, но и проектов на нем.

## {datetime.datetime.now().strftime('%d.%m.%Y')}

На данный момент на платформе: {repos_today_cnt} репозиториев

Топ 10 ЯП:

{top_10_languages.set_index('lang').to_markdown()}

## Будь добр, поставь звезду этому репозиторию
""")

    print("Успешно!")


def main():
    load_save_today_repos()
    mix_today_data_with_full_archive()
    update_readme()


if __name__ == "__main__":
    main()
